package com.hejia.alauda.event;

import static com.hejia.alauda.event.EventConstant.KEY_ADD_BONUS_RECEIVE_EVENT;
import static com.hejia.alauda.event.EventConstant.KEY_ANNUAL_MEETING_2015;
import static com.hejia.alauda.event.EventConstant.KEY_PAY_SUCCESS_EVENT;
import static com.hejia.alauda.event.EventConstant.KEY_USER_REGISTER_EVENT;
import static com.hejia.alauda.utils.Utils.formatDate;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.time.DateUtils.addYears;
import static org.springframework.util.CollectionUtils.isEmpty;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.springframework.context.ApplicationListener;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import com.hejia.alauda.entity.BonusOrder;
import com.hejia.alauda.entity.BonusReceive;
import com.hejia.alauda.entity.BonusRecord;
import com.hejia.alauda.entity.CreditOperation;
import com.hejia.alauda.entity.Financing;
import com.hejia.alauda.entity.Invitation;
import com.hejia.alauda.entity.Order;
import com.hejia.alauda.entity.Parameter;
import com.hejia.alauda.entity.User;
import com.hejia.alauda.entity.example.CreditOperationExample;
import com.hejia.alauda.entity.example.FinancingExample;
import com.hejia.alauda.persistence.mybatis.BankCardMapper;
import com.hejia.alauda.persistence.mybatis.BonusOrderMapper;
import com.hejia.alauda.persistence.mybatis.BonusReceiveMapper;
import com.hejia.alauda.persistence.mybatis.BonusRecordMapper;
import com.hejia.alauda.persistence.mybatis.CreditOperationMapper;
import com.hejia.alauda.persistence.mybatis.FinancingMapper;
import com.hejia.alauda.persistence.mybatis.InvitationMapper;
import com.hejia.alauda.persistence.mybatis.ParameterMapper;
import com.hejia.alauda.persistence.mybatis.UserMapper;
import com.hejia.alauda.service.ActivityService;
import com.hejia.alauda.service.BalanceAndFinancingService;
import com.hejia.alauda.service.BonusService;
import com.hejia.alauda.service.CommonService;
import com.hejia.alauda.service.ConfigureService;
import com.hejia.alauda.service.CreditService;
import com.hejia.alauda.service.MessageService;
import com.hejia.alauda.service.UserService;
import com.hejia.alauda.utils.Utils;

import java.util.*;

@Component
public class MessageListener implements ApplicationListener<MessageEvent> {
	
	static Log logger = LogFactory.getLog(MessageListener.class);
	
	static long BONUS2015_DEADLINE = 1424880000000L;
	
	
	@Resource
	CreditOperationMapper creditOperationMapper;
	
	@Resource
	BonusReceiveMapper bonusReceiveMapper;
	
	@Resource
	BonusRecordMapper bonusRecordMapper;
	
	@Resource
	FinancingMapper financingMapper;
	
	@Resource
	BonusOrderMapper bonusOrderMapper;
	
	@Resource
	UserService userService;
	
	@Resource
    ConfigureService configureService;
	
	@Resource
	BankCardMapper bankCardMapper;
	
	@Resource
	RedisTemplate<String, Object> redisTemplate;
	
	@Resource
	CommonService commonService;
	
	@Resource
	CreditService creditService;
	
	@Resource
	InvitationMapper invitationMapper;
	
	@Resource
	private MongoTemplate mongoTemplate;
	
	@Resource
	MessageService messageService;
	
	@Resource
	ParameterMapper parameterMapper;
	
	@Resource
	ActivityService activityService;
	
	@Resource
	BalanceAndFinancingService balanceAndFinancingService;
	
	@Resource
	UserMapper userMapper;
	
	@Resource
	BonusService bonusService;
	
	@Resource(name="executor")
	protected AsyncTaskExecutor executor;
	
	@Override
	public void onApplicationEvent(MessageEvent event) {
			
		int key = event.getWhat();
		
		if(key == KEY_ADD_BONUS_RECEIVE_EVENT){
			BonusReceive bonusReceive = (BonusReceive) event.getSource();
			User user = userService.findUserByMobile(bonusReceive.getReceiver());
			if(user != null){

				addBonusRecordByBonusReceive(bonusReceive, new Date(BONUS2015_DEADLINE), user);
			}
		} else if (key == KEY_USER_REGISTER_EVENT) {
			
			final User user = userService.findUserById((Long) event.getSource());
			
			boolean fromInvite = false;
			Invitation invitation = userService.getInvitation(user);
			if(user!=null && invitation!=null)
				fromInvite = true;
			
			//红包注册
			boolean fromRedPacket = false;
			if("P:295-298-583".equals(user.getReferee()))
				fromRedPacket= true;
			
			if(fromInvite || fromRedPacket){
				//creditService.addCreditOperation(Utils.REGISTER_CREDITS, user, CreditOperation.Operation.REGISTER, "注册赠送"+Utils.REGISTER_CREDITS+"积分");
				//如果是2015-02-01T00:00:00之后注册的就送20元红包
				try {
					bonusService.addBonusRecordByRedpacket(user, "INVITATION_INVITEE", new BigDecimal(10));
					bonusService.addBonusRecordByRedpacket(user, "INVITATION_INVITEE", new BigDecimal(10));
					
				} catch (Exception e) {
					e.printStackTrace();
				}
//				executor.execute(new Runnable() {
//					@Override
//					public void run() {
//						try {
//							activityService.handleBaiheRegisterBusiness(user);
//						} catch (Exception e) {
//							e.printStackTrace();
//						}
//					}
//				});
			}
			
			//188礼包
			if("P:295-313-592".equals(user.getReferee()) || "P:316-319-595".equals(user.getReferee())){
				bonusService.addBonusRecordByRedpacket(user, "KJC_BOND_5", new BigDecimal(5));
				bonusService.addBonusRecordByRedpacket(user, "KJC_BOND_5", new BigDecimal(5));
				bonusService.addBonusRecordByRedpacket(user, "KJC_BOND_10", new BigDecimal(10));
				bonusService.addBonusRecordByRedpacket(user, "KJC_BOND_10", new BigDecimal(10));
				bonusService.addBonusRecordByRedpacket(user, "KJC_BOND_20", new BigDecimal(20));
				bonusService.addBonusRecordByRedpacket(user, "KJC_BOND_50", new BigDecimal(50));
				bonusService.addBonusRecordByRedpacket(user, "KJC_BOND_88", new BigDecimal(88));
			}
			
			//188礼包
			if("android_jifengbao".equals(user.getReferee())){
				bonusService.addBonusRecordByRedpacket(user, "CHANNEL_BOND_5", new BigDecimal(5));
				bonusService.addBonusRecordByRedpacket(user, "CHANNEL_BOND_5", new BigDecimal(5));
				bonusService.addBonusRecordByRedpacket(user, "CHANNEL_BOND_10", new BigDecimal(10));
				bonusService.addBonusRecordByRedpacket(user, "CHANNEL_BOND_10", new BigDecimal(10));
				bonusService.addBonusRecordByRedpacket(user, "CHANNEL_BOND_20", new BigDecimal(20));
				bonusService.addBonusRecordByRedpacket(user, "CHANNEL_BOND_50", new BigDecimal(50));
				bonusService.addBonusRecordByRedpacket(user, "CHANNEL_BOND_88", new BigDecimal(88));
			}
			
			
			
		} else if(key == KEY_PAY_SUCCESS_EVENT) {
			/**
			 * 计算随着这笔交易能够获得的红包
			 */
			final Financing financing = financingMapper.selectByPrimaryKey((Long) event.getSource());
			logger.info("=========================>financing:" + financing);
			boolean devMode = Boolean.FALSE;
			if (event.arg1 != null)
				devMode = (Boolean) event.arg1;
			/**
			 * 查询资产的笔数 以后会用到
			 */
			FinancingExample financingExample = new FinancingExample();
			financingExample.appendCriterion("user_id=", financing.getUser().getId());
			final int financingCount = financingMapper.countByExample(financingExample);//资产记录数
			/**
			 * 非新手资产记录数
			 */
			financingExample = new FinancingExample();
			financingExample.appendCriterion("product_id IN(SELECT id FROM product WHERE rookie=FALSE)");
			financingExample.appendCriterion("user_id=", financing.getUser().getId());
			final int notRookieCount = financingMapper.countByExample(financingExample);
			/**
			 * 购买时间
			 */
			String buyTime = formatDate(financing.getOrder().getCreateDate());
			
			
			long orderTime = financing.getOrder().getCreateDate().getTime();
			logger.info("=====================>orderNumber:" + financing.getOrder().getOrderNumber() + ",orderTime:" + orderTime);
			logger.info("=====================>financingCount:" + financingCount);
			
			try {
				//最终成功后真正的激活所选的红包
				if (financing.getOrder() != null) {
					creditService.activateBonusRecord(financing.getOrder());
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			// 如果是首单，就去查询是否是邀请来的，给邀请人奖励
			if (financingCount == 1) {
				userService.sendInvitationMessage(financing);
			}

			/**
			 * 购买成功以后的积分处理
			 */
			/*executor.execute(new Runnable() {
				@Override
				public void run() {
					try {
						creditService.calculateProductCredits(financing);
						// 如果是首单，就去查询是否是邀请来的，给邀请人奖励
						if (financingCount == 1) {
							userService.sendInvitationMessage(financing);
						}

						if (Utils.formatDateTime(financing.getUser().getCreateDate())
								.compareTo(Utils.redenvelopeEndTime) >= 0) {

							if (financingCount > 0) {
								// 如果是没绑过卡的
								CreditOperationExample coExample = new CreditOperationExample();
								coExample.appendCriterion("user_id=", financing.getUser()
										.getId());
								coExample.appendCriterion("operation=",
										CreditOperation.Operation.BIND.toString());
								if (creditOperationMapper.countByExample(coExample) == 0) {
									creditService.addCreditOperation(Utils.BIND_CARD_CREDITS,
											financing.getUser(),
											CreditOperation.Operation.BIND, "首次绑卡赠送积分");
								}
							}
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});*/

		}
	}
	
	
	
	
	
	public void bonus2015creation(String mobile,Integer amount) {
		User user = this.userService.findUserByMobile(mobile);
		if(user!=null) {
			BigDecimal interest = new BigDecimal(amount
					* 0.065
					/ 360 * 7).setScale(2, RoundingMode.UP);
			BonusRecord record = new BonusRecord();
			record.setAmount(interest);
			record.setDescription(amount + "元虚拟理财金收益获得了" + record.getAmount() + "元的红包");
			record.setType("ANNUAL_MEETING_2015");
			record.setConsume(false);
			record.setUser(user);
			record.setRemaining(record.getAmount());
			record.setCreateDate(Calendar.getInstance().getTime());
			record.setModifyDate(record.getCreateDate());
			record.setExpiredDate(addYears(record.getCreateDate(), 1));
			bonusRecordMapper.insert(record);
		}
	}
	
	public void receiveRedEnvelopeByChannel(User user) {
		Parameter parameter = configureService.getParameter(Parameter.Category.Activity, "TV-shopping2015");
		if(user!=null&&parameter!=null){
			try {
				//从数据库获得配置参数
				Map<String, Object> config = Utils.getInstance().readValue(parameter.getValue(), Map.class);
				String startDate = (String) config.get("startDate"), endDate = (String) config.get("endDate");//开始结束时间
				Long deadline = (Long) config.get("deadline");//红包过期时间
				List<String> channels = (List<String>) config.get("channels");//获得红包的渠道
				if(startDate!=null && endDate!=null && deadline!=null && channels!=null){
					String now = Utils.formatDateTime_i18n(Calendar.getInstance());
					if(now.compareTo(startDate)>=0 && now.compareTo(endDate)<0){
						if(isNotBlank(user.getReferee()) && !isEmpty(channels) && channels.contains(user.getReferee())){
							BonusRecord record = new BonusRecord();
							record.setAmount(new BigDecimal("20"));
							record.setExpiredDate(new Date(deadline));
							record.setDescription("注册获得了" + record.getAmount() + "元的红包");
							record.setType("REGISTER2015");
							record.setConsume(false);
							record.setUser(user);
							record.setRemaining(record.getAmount());
							record.setCreateDate(Calendar.getInstance().getTime());
							record.setModifyDate(record.getCreateDate());
							bonusRecordMapper.insert(record);
						}
					}
				}
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 计算这笔订单可以返回多少红包
	 * @param bonusRecords
	 * @param order
	 */
	public void calculateBonus(List<BonusRecord> bonusRecords, Order order) {
		Date now = Calendar.getInstance().getTime();
		if(!isEmpty(bonusRecords)){
			//计算红包
			for(BonusRecord item : bonusRecords){
				
				Map<String, Object> params = new HashMap<String, Object>();
				params.put("id", item.getId());
				params.put("consume", Boolean.TRUE);
				params.put("consumeDate", now);
				params.put("remaining", 0);
				bonusRecordMapper.updateConsumeById(params);
				
				BonusOrder bonusOrder = new BonusOrder();
				bonusOrder.setCreateDate(now);
				bonusOrder.setModifyDate(now);
				bonusOrder.setAmount(item.getAmount());
				bonusOrder.setBonusRecord(item);
				bonusOrder.setOrder(order);
				bonusOrder.setRepaid(Boolean.FALSE);
				bonusOrderMapper.insert(bonusOrder);
			}
		}
	}
	
	public void addBonusRecordByBonusReceive(BonusReceive bonusReceive, Date expiredDate, User user) {
		BonusRecord record = new BonusRecord();
		record.setAmount(bonusReceive.getAmount());
		record.setExpiredDate(expiredDate);
		record.setDescription("您获得了新春活动的" + record.getAmount() + "元的红包");
		record.setType("BONUS2015");
		record.setConsume(false);
		record.setUser(user);
		record.setRemaining(record.getAmount());
		record.setCreateDate(bonusReceive.getCreateDate());
		record.setModifyDate(bonusReceive.getCreateDate());
		bonusRecordMapper.insert(record);
		
		bonusReceive.setBonusRecord(record);
		bonusReceiveMapper.updateByPrimaryKey(bonusReceive);
	}
	
}
